﻿//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_STL_Ext.h".
//-------------------------------------------------------------------

#ifndef _UXS_GL_PRIMITIVES_H
#define _UXS_GL_PRIMITIVES_H

#pragma once

#include "../shell/GLCommon.h"

namespace UX_STL
{
namespace GLShell
{

#pragma pack(push, 1)

	//
	// Vertex 2D
	//

	struct TVertex2D
	{
		fvec3		sPos,
					sTexCoord;
		color4u		sColor;
		///
		TVertex2D() {}
		TVertex2D(const fvec2 &pos, const color4u &color = color4u()):  sPos(pos), sTexCoord(), sColor(color) {}	// point
		TVertex2D(const fvec3 &pos, const color4u &color = color4u()):  sPos(pos), sTexCoord(), sColor(color) {} // point
		TVertex2D(const fvec2 &pos, const fvec2 &tex, const color4u &color = color4u()):  sPos(pos), sTexCoord(tex), sColor(color) {}
		TVertex2D(const fvec3 &pos, const fvec2 &tex, const color4u &color = color4u()):  sPos(pos), sTexCoord(tex), sColor(color) {}
	};


	//
	// Line 2D
	//

	struct TLine2D
	{
		TVertex2D	sPoint0,
					sPoint1;
		///
		TLine2D() {}
		TLine2D(const fvec2 &p0, const fvec2 &p1, const color4u &color = color4u()):  sPoint0(p0, color), sPoint1(p1, color) {}
		TLine2D(const fvec3 &p0, const fvec3 &p1, const color4u &color = color4u()):  sPoint0(p0, color), sPoint1(p1, color) {}
	};


	//
	// Triangle 2D
	//

	struct TTriangle2D
	{
		TVertex2D	sPoint0,
					sPoint1,
					sPoint2;
		///
		TTriangle2D() {}
		TTriangle2D(const TVertex2D &p0, const TVertex2D &p1, const TVertex2D &p2):  sPoint0(p0), sPoint1(p1), sPoint2(p2) {}
	};


	//
	// Quad 2D
	//

	struct TQuad2D
	{
		frect		sRect;
		frect		sTexCoord;
		color4u		sColor;
		float		fDepth;
		///
		TQuad2D() {}
		TQuad2D(const frect &pos, const frect &tex, const color4u &color = color4u(), float depth = 0.f):
			sRect(pos), sTexCoord(tex), sColor(color), fDepth(depth) {}
	};


	//
	// Rect 2D
	//

	struct TRect2D
	{
		TVertex2D	sPoint0,	// left bottom
					sPoint1,	// left top
					sPoint2,	// right bottom
					sPoint3;	// right top
		///
		TRect2D() {}
		TRect2D(const TQuad2D &q):
					sPoint0( fvec3(q.sRect.left,  q.sRect.bottom, q.fDepth), fvec2(q.sTexCoord.left,  q.sTexCoord.top),    q.sColor ),
					sPoint1( fvec3(q.sRect.left,  q.sRect.top,    q.fDepth), fvec2(q.sTexCoord.left,  q.sTexCoord.bottom), q.sColor ),
					sPoint2( fvec3(q.sRect.right, q.sRect.bottom, q.fDepth), fvec2(q.sTexCoord.right, q.sTexCoord.top),    q.sColor ),
					sPoint3( fvec3(q.sRect.right, q.sRect.top,    q.fDepth), fvec2(q.sTexCoord.right, q.sTexCoord.bottom), q.sColor ) {}

		TRect2D(const frect &pos, const frect &tex, const color4u aColors[4], float depth = 0.f):
					sPoint0( fvec3(pos.left,  pos.bottom, depth), fvec2(tex.left,  tex.top),    aColors[0] ),
					sPoint1( fvec3(pos.left,  pos.top,    depth), fvec2(tex.left,  tex.bottom), aColors[1] ),
					sPoint2( fvec3(pos.right, pos.bottom, depth), fvec2(tex.right, tex.top),    aColors[2] ),
					sPoint3( fvec3(pos.right, pos.top,    depth), fvec2(tex.right, tex.bottom), aColors[3] ) {}

		TRect2D(const TVertex2D &lt, const TVertex2D &lb, const TVertex2D &rb, const TVertex2D &rt):
					sPoint0(lt), sPoint1(lb), sPoint2(rt), sPoint3(rb) {}
	};


	//
	// Rect 2D (6 points)
	//

	struct TRect2D_6p
	{
		TTriangle2D	sTriangle0,		// lt, lb, rt
					sTriangle1;		// lb, rt, rb
		///
		TRect2D_6p() {}
		TRect2D_6p(const TRect2D &r):
					sTriangle0(r.sPoint0, r.sPoint1, r.sPoint2),
					sTriangle1(r.sPoint1, r.sPoint2, r.sPoint3) {}
		TRect2D_6p(const TTriangle2D &t0, const TTriangle2D &t1):
					sTriangle0(t0), sTriangle1(t1) {}
	};


	//
	// Vertex 3D
	//

	struct TVertex3D
	{
		fvec3		sPos,
					sNormal;
		fvec2		sTexCoord;
		///
		TVertex3D() {}
		TVertex3D(const fvec3 &pos, const fvec2 &tex = fvec2(), const fvec3 &normal = fvec3()):  sPos(pos), sTexCoord(tex), sNormal(normal) {}
	};


	//
	// Line 3D
	//

	struct TLine3D
	{
		TVertex3D	sPoint0,
					sPoint1;
		///
		TLine3D() {}
		TLine3D(const fvec3 &p0, const fvec3 &p1):  sPoint0(p0), sPoint1(p1) {}
	};


	//
	// Triangle 3D
	//

	struct TTriangle3D
	{
		TVertex3D	sPoint0,
					sPoint1,
					sPoint2;
		///
		TTriangle3D() {}
		TTriangle3D(const TVertex3D &p0, const TVertex3D &p1, const TVertex3D &p2):  sPoint0(p0), sPoint1(p1), sPoint2(p2) {}
	};


	//
	// Rect 3D
	//

	struct TRect3D
	{
		TVertex3D	sPoint0,	// left top
					sPoint1,	// left bottom
					sPoint2,	// right top
					sPoint3;	// right bottom
		///
		TRect3D() {}

		TRect3D(const frect &pos, const frect &tex, const fvec3 &normal, float depth = 0.f):
					sPoint0( fvec3(pos.left,  pos.bottom, depth), fvec2(tex.left,  tex.top),    normal ),
					sPoint1( fvec3(pos.left,  pos.top,    depth), fvec2(tex.left,  tex.bottom), normal ),
					sPoint2( fvec3(pos.right, pos.bottom, depth), fvec2(tex.right, tex.top),    normal ),
					sPoint3( fvec3(pos.right, pos.top,    depth), fvec2(tex.right, tex.bottom), normal ) {}

		TRect3D(const TVertex3D &lt, const TVertex3D &lb, const TVertex3D &rb, const TVertex3D &rt):
					sPoint0(lt), sPoint1(lb), sPoint2(rt), sPoint3(rb) {}
	};

#pragma pack(pop)

//-------------------------------------------------------------------

}	// GLShell
}	// UX_STL

#endif	// _UXS_GL_PRIMITIVES_H